/*
 * @FileName: bsp_uart.c
 * @Author: GreyQiu qiushaogui@aikosolar.com
 * @Date: 2023-08-21 10:50:15
 * @LastEditors: GreyQiu qiushaogui@aikosolar.com
 * @LastEditTime: 2023-09-20 14:35:30
 * @Description: 
 * 
 * Copyright (c) 2023, All Rights Reserved. 
 */

#include "bsp_uart.h"
#include "mb_rtu_m.h"

static uint8_t rx_buffer[WIFI_RX_LEN_MAX];

static uint8_t hmi_rx_buffer[WIFI_RX_LEN_MAX];

static uart_rx_complete_calllback rx_callback = NULL;



void dsp_dma_config(void)
{
    DMA_InitType DMA_InitStructure;

    RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_DMA); // 使能DMA时钟

    /* USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */
    DMA_Reset(MB_TX_DMA_CH);
    DMA_InitStructure.PeriphAddr     = (uint32_t)(&(UART_DSP->DAT));
    DMA_InitStructure.MemAddr        = (uint32_t)rx_buffer;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_DST;
    DMA_InitStructure.BufSize        = WIFI_TX_LEN_MAX;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_MODE_DISABLE;
    DMA_InitStructure.MemoryInc      = DMA_MEM_INC_MODE_ENABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_WIDTH_BYTE;
    DMA_InitStructure.MemDataSize    = DMA_MEM_DATA_WIDTH_BYTE;
    DMA_InitStructure.CircularMode   = DMA_CIRCULAR_MODE_DISABLE;
    DMA_InitStructure.Priority       = DMA_CH_PRIORITY_HIGH;
    DMA_InitStructure.Mem2Mem        = DMA_MEM2MEM_DISABLE;
    DMA_Initializes(MB_TX_DMA_CH, &DMA_InitStructure);
    DMA_Channel_Request_Remap(MB_TX_DMA_CH, DMA_REMAP_USART1_TX);

    /* USARTy RX DMA1 Channel (triggered by USARTy Rx event) Config */
    DMA_Reset(MB_RX_DMA_CH);
    DMA_InitStructure.PeriphAddr = (uint32_t)(&(UART_DSP->DAT));
    DMA_InitStructure.MemAddr    = (uint32_t)ModBusCom.rxBuf;
    DMA_InitStructure.Direction  = DMA_DIR_PERIPH_SRC;
    DMA_InitStructure.BufSize    = WIFI_RX_LEN_MAX;
    DMA_Initializes(MB_RX_DMA_CH, &DMA_InitStructure);
    DMA_Channel_Request_Remap(MB_RX_DMA_CH, DMA_REMAP_USART1_RX);
}

void hmi_dma_config(void)
{
    DMA_InitType DMA_InitStructure;

    RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_DMA); // 使能DMA时钟

    /* USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */
    DMA_Reset(HMI_TX_DMA_CH);
    DMA_InitStructure.PeriphAddr     = (uint32_t)(&(UART_HMI->DAT));
    DMA_InitStructure.MemAddr        = (uint32_t)rx_buffer;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_DST;
    DMA_InitStructure.BufSize        = WIFI_TX_LEN_MAX;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_MODE_DISABLE;
    DMA_InitStructure.MemoryInc      = DMA_MEM_INC_MODE_ENABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_WIDTH_BYTE;
    DMA_InitStructure.MemDataSize    = DMA_MEM_DATA_WIDTH_BYTE;
    DMA_InitStructure.CircularMode   = DMA_CIRCULAR_MODE_DISABLE;
    DMA_InitStructure.Priority       = DMA_CH_PRIORITY_HIGH;
    DMA_InitStructure.Mem2Mem        = DMA_MEM2MEM_DISABLE;
    DMA_Initializes(HMI_TX_DMA_CH, &DMA_InitStructure);
    DMA_Channel_Request_Remap(HMI_TX_DMA_CH, DMA_REMAP_USART2_TX);

    /* USARTy RX DMA1 Channel (triggered by USARTy Rx event) Config */
    DMA_Reset(HMI_RX_DMA_CH);
    DMA_InitStructure.PeriphAddr = (uint32_t)(&(UART_HMI->DAT));
    DMA_InitStructure.MemAddr    = (uint32_t)ModBusCom.rxBuf;
    DMA_InitStructure.Direction  = DMA_DIR_PERIPH_SRC;
    DMA_InitStructure.BufSize    = WIFI_RX_LEN_MAX;
    DMA_Initializes(HMI_RX_DMA_CH, &DMA_InitStructure);
    DMA_Channel_Request_Remap(HMI_RX_DMA_CH, DMA_REMAP_USART2_RX);
}

void bsp_uart_init(void)
{
    USART_InitType USART_InitStructure;

    RCC_APB1_Peripheral_Clock_Enable(RCC_APB1_PERIPH_USART2); // 调试串口
    RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_USART1); // WIFI串口
    USART_Reset(UART_DSP);

    USART_InitStructure.BaudRate            = UART_BAUDRATE;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.Mode                = USART_MODE_TX | USART_MODE_RX;
    DMA_Channel_Disable(MB_RX_DMA_CH);
    DMA_Channel_Disable(MB_TX_DMA_CH);
    USART_Interrput_Disable(UART_DSP, USART_INT_IDLEF);

    dsp_dma_config();

    USART_Initializes(UART_DSP, &USART_InitStructure);

    USART_DMA_Transfer_Enable(UART_DSP, USART_DMAREQ_RX | USART_DMAREQ_TX);
    DMA_Channel_Disable(MB_RX_DMA_CH);

    USART_Enable(UART_DSP);


    USART_Reset(UART_HMI);

    USART_InitStructure.BaudRate            = UART_BAUDRATE;
    USART_InitStructure.WordLength          = USART_WL_8B;
    USART_InitStructure.StopBits            = USART_STPB_1;
    USART_InitStructure.Parity              = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.Mode                = USART_MODE_TX | USART_MODE_RX;
    DMA_Channel_Disable(HMI_RX_DMA_CH);
    DMA_Channel_Disable(HMI_TX_DMA_CH);
    USART_Interrput_Disable(UART_HMI, USART_INT_IDLEF);


    hmi_dma_config();

    USART_Initializes(UART_HMI, &USART_InitStructure);

    USART_DMA_Transfer_Enable(UART_HMI, USART_DMAREQ_RX | USART_DMAREQ_TX);
    DMA_Channel_Disable(HMI_RX_DMA_CH);

    USART_Enable(UART_HMI);
}

void bsp_uart_send(uint8_t * buffer, uint32_t len)
{
        DMA_Channel_Disable(MB_TX_DMA_CH);
        DMA_Memory_Address_Config(MB_TX_DMA_CH, (uint32_t)buffer);
        DMA_Buffer_Size_Config(MB_TX_DMA_CH, len);
        DMA_Channel_Enable(MB_TX_DMA_CH);

}

void bsp_uart_hmi_send(uint8_t * buffer, uint32_t len)
{
        DMA_Channel_Disable(HMI_TX_DMA_CH);
        DMA_Memory_Address_Config(HMI_TX_DMA_CH, (uint32_t)buffer);
        DMA_Buffer_Size_Config(HMI_TX_DMA_CH, len);
        DMA_Channel_Enable(HMI_TX_DMA_CH);
}

bool bsp_uart_send_complete(void)
{
    return DMA_Flag_Status_Get(DMA, MB_TX_DMA_FLAG); 
}

void bsp_uart_dma_read_start(uint8_t * buffer, uint16_t len)
{
    DMA_Channel_Disable(MB_RX_DMA_CH);
    DMA_Memory_Address_Config(MB_RX_DMA_CH, (uint32_t)buffer);
    DMA_Current_Data_Transfer_Number_Set(MB_RX_DMA_CH, len);
    DMA_Channel_Enable(MB_RX_DMA_CH);

}

void bsp_uart_dma_read_stop(void)
{
    DMA_Channel_Disable(MB_RX_DMA_CH);
}

bool bsp_uart_read_complete(void)
{
    if (USART_Flag_Status_Get(UART_DSP, USART_FLAG_IDLEF) == SET)
    {
        USART_Flag_Clear(UART_DSP, USART_FLAG_IDLEF);
        return true;
    }

    return false;
}

void bsp_uart_clear_error(void)
{
    uint32_t len;
    if (USART_Flag_Status_Get(UART_DSP, USART_FLAG_OREF | USART_FLAG_NEF | USART_FLAG_FEF | USART_FLAG_PEF) == SET)
    {
        USART_Flag_Clear(UART_DSP, USART_FLAG_IDLEF);
        len = USART_Data_Receive(UART_DSP);
        bsp_uart_init();
    }
    
    if (USART_Flag_Status_Get(UART_HMI, USART_FLAG_OREF | USART_FLAG_NEF | USART_FLAG_FEF | USART_FLAG_PEF) == SET)
    {
        USART_Flag_Clear(UART_HMI, USART_FLAG_IDLEF);
        len = USART_Data_Receive(UART_HMI);
        bsp_uart_init();
    }
}

void bsp_wifi_uart_callback_register(uart_rx_complete_calllback cb)
{
    rx_callback = cb;
}


void USART2_IRQHandler(void)
{
    uint32_t len;
    if (USART_Flag_Status_Get(USART2, USART_FLAG_IDLEF) == SET)
    {
        // if (rx_callback != NULL) {
        //     len = WIFI_RX_LEN_MAX - DMA_Current_Data_Transfer_Number_Get(MB_RX_DMA_CH);
        //     rx_callback(rx_buffer, len);
        // }
        // bsp_wifi_uart_rx_reset();
        // COM_rxProcess(&ModBusCom);
//        bsp_uart_dma_read(ModBusCom.rxBuf, ModBusCom.rxBufSize);
        len = USART_Data_Receive(USART2);
        USART_Flag_Clear(USART2, USART_FLAG_IDLEF);
    }
}
